package com.fingard.dsp.bank.directbank.cgbunion01;

import com.fingard.dsp.bank.directConfig.ActSetItem;
import com.fingard.dsp.bank.directbank.bankInterface.IOtherElse;
import com.fingard.dsp.bank.directbank.cgbunion01.util.FileHelper;
import com.fingard.dsp.bank.directbank.cgbunion01.util.MD5Utils;
import com.fingard.dsp.bank.directbank.cgbunion01.util.SM2SignUtils;
import com.fingard.dsp.bank.directbank.cgbunion01.util.SM4Utils;
import com.fingard.dsp.bank.reqrespobj.otherelse.ReqOtherElse;
import com.fingard.dsp.bank.reqrespobj.otherelse.RetAtsOtherElse;
import com.fingard.text.StringHelper;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang.StringEscapeUtils;

import java.util.HashMap;

public class CGBUnion01OtherElse extends CGBUnion01Base implements IOtherElse {
    @Override
    public RetAtsOtherElse d_else(ReqOtherElse p_reqElse) throws Exception {
        String transType = p_reqElse.reqHeader.transType;

        if ("VerifySign".equals(transType)) {
            return d_verifySign(p_reqElse);
        } else if ("UnifiedSign".equals(transType)) {
            return d_unifiedSign(p_reqElse);
        } else {
            RetAtsOtherElse retAts = new RetAtsOtherElse(p_reqElse.reqHeader);
            retAts.retHashMap = new HashMap<String, String>();
            retAts.retHashMap.put("RespCode", "-1");
            retAts.retHashMap.put("RespInfo", "未知的TransType：" + transType);
            return retAts;
        }
    }

    public RetAtsOtherElse d_verifySign(ReqOtherElse p_reqElse) {
        RetAtsOtherElse retAts = new RetAtsOtherElse(p_reqElse.reqHeader);
        retAts.retHashMap = new HashMap<String, String>();
        try {
            String ownAct = "";
            if (p_reqElse.reqHashMap.containsKey("OurBankAccount")) {
                ownAct = p_reqElse.reqHashMap.get("OurBankAccount");
            }
            ActSetItem actItem = this.getBankConfig().getActSetItem(ownAct, "");
            if (actItem != null) {
                String encryptKey = "";
                if (p_reqElse.reqHashMap.containsKey("EncryptKey")) {
                    encryptKey = p_reqElse.reqHashMap.get("EncryptKey");
                    encryptKey = SM2SignUtils.decryptString(FileHelper.loadFileBytes(actItem.oppCertFilePath, actItem.ownKeyStorePath), encryptKey, getCharset());
                }
                String plain = "";
                if (p_reqElse.reqHashMap.containsKey("Plain")) {
                    plain = StringEscapeUtils.unescapeHtml(p_reqElse.reqHashMap.get("Plain"));
                    plain = SM4Utils.SM4DecryptData(encryptKey, plain, getCharset());
                } else {
                    retAts.retHashMap.put("RespCode", "-1");
                    retAts.retHashMap.put("RespInfo", "缺失验签原始串");
                    return retAts;
                }
                String sign = "";
                if (p_reqElse.reqHashMap.containsKey("Sign")) {
                    sign = StringEscapeUtils.unescapeHtml(p_reqElse.reqHashMap.get("Sign"));
                }
                WriteBankLogLn("广发聚合支付通知报文：" + plain);
                retAts.retHashMap.put("PlainText", plain);

                StringBuilder tmpSb = new StringBuilder();
                if (verifySign(actItem, sign, plain)) {
                    retAts.retHashMap.put("RespCode", "0");
                    retAts.retHashMap.put("RespInfo", "验签通过");
                } else {
                    retAts.retHashMap.put("RespCode", "-1");
                    retAts.retHashMap.put("RespInfo", tmpSb.toString());
                }
            } else {
                retAts.retHashMap.put("RespCode", "-1");
                retAts.retHashMap.put("RespInfo", "未找到账号[" + ownAct + "]商户配置信息");
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            retAts.retHashMap.put("RespCode", "-1");
            retAts.retHashMap.put("RespInfo", ex.getMessage());
            WriteBankLogLn(ex);
        }
        return retAts;
    }

    public RetAtsOtherElse d_unifiedSign(ReqOtherElse p_reqElse) {
        RetAtsOtherElse retAts = new RetAtsOtherElse(p_reqElse.reqHeader);
        retAts.retHashMap = new HashMap<String, String>();
        try {
            String ownAct = "";
            if (p_reqElse.reqHashMap.containsKey("OurBankAccount")) {
                ownAct = p_reqElse.reqHashMap.get("OurBankAccount");
            }
            ActSetItem actItem = this.getBankConfig().getActSetItem(ownAct, "");
            if (actItem != null) {
                String plainText = p_reqElse.reqHashMap.get("PlainText");
                String verifyChars = "123457890abcdefghijklmnopqrstuvwxyz";
                RandomStringUtils rs = new RandomStringUtils();
                String encryptKey = rs.random(16, verifyChars).toUpperCase();
                String requestEncryptJson = SM4Utils.SM4EncryptData(encryptKey, plainText, getCharset());
                WriteBankLogLn("encryptKey:" + encryptKey);
                WriteBankLogLn("requestEncryptJson加密报文:" + requestEncryptJson);

                // 对原报文签名
                String requestSignatureJson = SM2SignUtils.signString(plainText, FileHelper.loadFileBytes(actItem.oppCertFilePath, actItem.ownKeyStorePath), getCharset());
                // 证书ID，使用公钥MD5值
                String certId = MD5Utils.getMD5(FileHelper.loadFileBytes(actItem.oppCertFilePath, actItem.webAPISercretKey));
                WriteBankLogLn("certId:" + certId);
                WriteBankLogLn("requestSignatureJson签名字符串:" + requestSignatureJson);

                // 对报文加密密钥加密，使用广发公钥进行加密
                String keyToEncry = SM2SignUtils.encryptString(FileHelper.loadFileBytes(actItem.oppCertFilePath, actItem.ownCertFilePath), encryptKey, getCharset());

                if (StringHelper.hasAnyChar(requestSignatureJson)) {
                    retAts.retHashMap.put("RespCode", "0");
                    retAts.retHashMap.put("RespInfo", "签名成功!");
                    retAts.retHashMap.put("Result", requestSignatureJson);
                    retAts.retHashMap.put("EncryptMsg", requestEncryptJson);
                    retAts.retHashMap.put("EncryptKey", keyToEncry);
                    retAts.retHashMap.put("SignType", "SM2");
                    retAts.retHashMap.put("CertId", certId);
                    retAts.retHashMap.put("EncryptType", "SM4");
                } else {
                    retAts.retHashMap.put("RespCode", "-1");
                    retAts.retHashMap.put("RespInfo", "签名失败!");
                }
            } else {
                retAts.retHashMap.put("RespCode", "-1");
                retAts.retHashMap.put("RespInfo", "未找到账号[" + ownAct + "]商户配置信息");
            }

        } catch (Exception ex) {
            ex.printStackTrace();
            retAts.retHashMap.put("RespCode", "-1");
            retAts.retHashMap.put("RespInfo", ex.getMessage());
            WriteBankLogLn(ex);
        }
        return retAts;
    }
}
